package cn.mw.cmdb.processor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.mw.cmdb.entity.*;
import cn.mw.cmdb.enums.TableViewTypeEnum;
import cn.mw.cmdb.param.InstanceSearchParam;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.CustomModelServiceImpl;
import cn.mw.cmdb.service.impl.InstanceServiceImpl;
import cn.mw.cmdb.service.impl.ModelPropertyServiceImpl;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.components.mongodb.entity.SubCondition;
import cn.mw.microMonitorCommon.api.cmdb.TableIdEnum;
import cn.mw.microMonitorCommon.api.cmdb.TreeView;
import cn.mw.microMonitorCommon.util.ModuleIDManager;
import cn.mw.microMonitorCommon.util.SpringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.mw.cmdb.entity.InstanceInfo.SearchPrefix;
import static cn.mw.components.mongodb.entity.MongoPropertyType.strValueConvert;

/**
 * 使用地点分组
 */
public class TreeProcessorLocation implements TreeProccessorTable {
    private CmdbServiceManage cmdbServiceManage;

    public static String locationKey = "Officebuildingname";
    private String locationKeyPath = SearchPrefix + "." + locationKey;

    public TreeProcessorLocation(CmdbServiceManage cmdbServiceManage) {
        this.cmdbServiceManage = cmdbServiceManage;
    }

    @Override
    public List genTreeData(TableDataProcessorContext context) throws Exception {
        List<TreeView> ret = new ArrayList<>();
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);

        List<String> fields = new ArrayList<>();
        fields.add(CMDBTool.getFieldName(InstanceInfo::getId));
        fields.add(CMDBTool.getFieldName(InstanceInfo::getPath));
        fields.add(CMDBTool.getFieldName(InstanceInfo::getInstanceName));
        fields.add(CMDBTool.getFieldName(InstanceInfo::getOrgs));
        fields.add(CMDBTool.getFieldName(InstanceInfo::getOrgIds));
        fields.add(CMDBTool.getFieldName(InstanceInfo::getData));
        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        instanceSearchParam.setFields(fields);
        SubCondition subCondition = new SubCondition(CriteriaOpsType.ne.name(), null);
        instanceSearchParam.addSubCondition(locationKey, subCondition);

        ModelPropertyServiceImpl propertyService = (ModelPropertyServiceImpl) cmdbServiceManage.getModelService(ModelPropertyServiceImpl.ID);
        //获取模型对应的全部属性集合(包含父模型的属性)
        Map<String, List<PropertyInfo>> modelAllPropertyList = propertyService.getModelAllPropertyList(new ArrayList<>(), null);
        BeanUtil.copyProperties(context.getTableSearchParam(), instanceSearchParam, CopyOptions.create().setIgnoreNullValue(true));
        CustomModelServiceImpl modelService = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);

        List<InstanceInfoExtend> list = instanceService.aggregateList(instanceSearchParam);
        //如果指定了金融元父模型，过滤其他的金融元父模型
        List<ModelInfo> financeParentModelInfos = modelService.getFinanceParentModelInfos();
        Map<String, ModelInfo> modelId2FinanceParentModelInfoMap = financeParentModelInfos.stream().collect(Collectors.toMap(ModelInfo::getId, item -> item, (o1, o2) -> o1));
        List<String> financeParentModelIds = financeParentModelInfos.stream().map(ModelInfo::getId).toList();
        for (InstanceInfoExtend instanceInfoExtend : list) {
            String modelId = instanceInfoExtend.getModelId();
            List<PropertyInfo> propertyInfoList = modelAllPropertyList.get(modelId);
            String financeParentId = instanceInfoExtend.getFinanceParentId();
            instanceService.filterFinanceParentModelProperty(propertyInfoList, modelId2FinanceParentModelInfoMap.get(financeParentId), financeParentModelIds);
            //获取属性id->属性名称
            Map<String, PropertyInfo> propertyById = propertyInfoList.stream().collect(Collectors.toMap(s -> s.getId(), s -> s, (
                    value1, value2) -> {
                return value2;
            }));
            if (propertyById != null && propertyById.containsKey(locationKey)) {
                PropertyInfo propertyInfo = propertyById.get(locationKey);
                if (propertyInfo != null) {
                    PropertyType propertyType = propertyInfo.getPropertyType();
                    Object obj = propertyType.exportValue(instanceInfoExtend.getData().get(locationKey), null);
                    instanceInfoExtend.getData().put(locationKey, obj);
                }
            }
        }
        Map<String, List<InstanceInfo>> collect = list.stream().collect(Collectors.groupingBy(s -> strValueConvert(s.getData().get(locationKey))));
        ModuleIDManager moduleIDManager = SpringUtils.getBean(ModuleIDManager.class);
        collect.forEach((k, v) -> {
            String itemName = k;
            List<InstanceInfo> instanceInfos = v;
            ModelSystemTreeViewInfo treeViewInfo = new ModelSystemTreeViewInfo();
            treeViewInfo.setItemName(itemName);
            treeViewInfo.setId(itemName);
            treeViewInfo.setType(TableIdEnum.location.name());
            treeViewInfo.setParentId(null);
            treeViewInfo.setViewType(TableViewTypeEnum.list.getCode());
            treeViewInfo.setCount(instanceInfos.size());
            ret.add(treeViewInfo);
        });
        return ret;
    }
}
